using System;
using System.Collections.Generic;
using System.Text;

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Security;

using WMOSSExperts.Fields;

namespace WMOSSExperts.WebControls
{

    [CLSCompliant(false)]
    public class AdvancedLookupFieldEditor : UserControl, IFieldEditor
    {
        #region "Interface element defintion"
        protected DropDownList DdlLookupFieldTargetWeb;
        protected DropDownList DdlLookupFieldTargetList;
        protected DropDownList DdlLookupFieldTargetField;
        protected CheckBox cbxAllowMultiValue;
        protected CheckBox cbxUnlimitedLengthInDocLib;
        protected MultiView MVSelectConfiguration;
        protected CheckBox ChkShowInDisplayForm;
        protected CheckBoxList CblAdditionalFields;

        #endregion

        protected AdvancedLookupField _lookupField;

        /// <summary>
        /// Reload dropdown lists (lists and fields) when a new web is selected
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void DdlLookupFieldTargetWeb_Changed(object sender, EventArgs e)
        {
            this.FillList(Guid.Empty);
            this.FillFields(String.Empty);
            this.Page.SetFocus(this.DdlLookupFieldTargetList);
        }

 
        /// <summary>
        /// Reload dropdown list for fields when a new list is selected
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void DdlLookupFieldTargetList_Changed(object sender, EventArgs e)
        {
            this.FillFields(String.Empty);
            this.Page.SetFocus(this.DdlLookupFieldTargetList);

        }

        #region "Fill dropdown lists"
        

        /// <summary>
        /// Add field to dropdown lis
        /// </summary>
        /// <param name="showField"></param>
        /// <param name="field"></param>
        /// <param name="strSelectedField"></param>
        /// <param name="extraText"></param>
        private ListItem AddFieldToListControl(ListControl showField, SPField field, List<String> selectedFields, string extraText)
        {
            ListItem item = new ListItem();
            item.Text = field.Title + " " + field.AuthoringInfo + " ";
            if (!string.IsNullOrEmpty(extraText))
            {
                item.Text = item.Text + extraText;
            }
            item.Value = field.InternalName;
           

            if (selectedFields != null && selectedFields.Contains(field.InternalName))
                item.Selected = true;

            showField.Items.Add(item);
            return item;
        }



        /// <summary>
        /// Gets the Current site in the SPContext. Don't dispose this object
        /// </summary>
        private SPSite CurrentSite
        {
            get
            {
                return SPContext.Current.Site;
            }
        }

        /// <summary>
        /// Get the selected web from its dropdown list
        /// </summary>
        /// <returns></returns>
        private SPWeb GetSelectedWeb()
        {
            if (DdlLookupFieldTargetWeb.SelectedIndex < 0) return null;

            ListItem selected = DdlLookupFieldTargetWeb.Items[DdlLookupFieldTargetWeb.SelectedIndex];
            Guid webId = new Guid(selected.Value);

            return this.CurrentSite.OpenWeb(webId);

        }

        /// <summary>
        /// Fill all webs from this site collection
        /// </summary>
        private void FillWebs(Guid selectedWeb)
        {
            DdlLookupFieldTargetWeb.Items.Clear();
            SPWebCollection webs  = SPContext.Current.Site.AllWebs;
            Int32 selectedIndex = 0;
            foreach (SPWeb web in webs)
            {
                DdlLookupFieldTargetWeb.Items.Add(new ListItem(web.Title, web.ID.ToString()));
                if (selectedWeb.CompareTo(web.ID) == 0) selectedIndex = DdlLookupFieldTargetWeb.Items.Count - 1;
            }

            DdlLookupFieldTargetWeb.SelectedIndex = selectedIndex;
        }

        private void FillList(Guid selectedList)
        {
            DdlLookupFieldTargetList.Items.Clear();

            Int32 selectedIndex = 0;
            using (SPWeb web = this.GetSelectedWeb())
            {
                foreach (SPList list in web.Lists)
                {
                    if (list.Hidden) continue;
                    DdlLookupFieldTargetList.Items.Add(new ListItem(list.Title, list.ID.ToString()));
                    if (selectedList.CompareTo(list.ID) == 0) selectedIndex = DdlLookupFieldTargetList.Items.Count - 1;
                }
            }

            DdlLookupFieldTargetList.SelectedIndex = selectedIndex;

        }

        private void FillFields(String fieldInternalName)
        {
            DdlLookupFieldTargetField.Items.Clear();
            //TODO Additional Fields
            //CblAdditionalFields.Items.Clear();

            using (SPWeb web = this.GetSelectedWeb())
            {
                ListItem selected = DdlLookupFieldTargetList.Items[DdlLookupFieldTargetList.SelectedIndex];
                Guid listId = new Guid(selected.Value);
                SPList list = web.Lists[listId];

                SPFieldCollection fields = list.Fields;
                Int32 selectedIndex = 0;

                //TODO Additional Fields
                //List<String> additionalFields = null;
                //if (_lookupField != null) additionalFields = _lookupField.GetCurrentAdditionalFields();

                foreach(SPField field in fields)
                {
                    if (field.Hidden) continue;
                    if (field is SPFieldComputed && !((SPFieldComputed)field).EnableLookup) continue;
                    if (field is SPFieldCalculated && ((SPFieldCalculated)field).OutputType != SPFieldType.Text) continue;
                    if (field is AdvancedLookupField | field is SPFieldLookup) continue;
                    if (field is RelatedLookupLinksField) continue;

                    //Add the field in the dropdown list to select the main field
                    this.AddFieldToListControl(DdlLookupFieldTargetField, field, null, null);
                    if (String.Compare(field.InternalName, fieldInternalName, true) == 0) selectedIndex = DdlLookupFieldTargetField.Items.Count - 1;

                    //TODO Additional Fields
                    //ListItem item = this.AddFieldToListControl(CblAdditionalFields, field, additionalFields, null);
                    //item.Attributes.Add("class", "ms-authoringcontrols");
                }

                DdlLookupFieldTargetField.SelectedIndex = selectedIndex;
            }
        }

        #endregion

        #region IFieldEditor Members

        public bool DisplayAsNewSection
        {
            get { return false; }
        }

        public void InitializeWithField(SPField field)
        {
            _lookupField = (field as AdvancedLookupField);

            if (this.IsPostBack) return;

            String fieldInternalName = String.Empty;
            Guid webId = Guid.Empty;
            Guid listId = Guid.Empty;
            String reverseLookupId = String.Empty;
            MVSelectConfiguration.ActiveViewIndex = 0;

            if (field != null)
            {
                //Edit mode, this reverseLookupField already exists
                AdvancedLookupField lookup = (field as AdvancedLookupField);
                if (lookup.CountRelated | !String.IsNullOrEmpty(lookup.RelatedField))
                {
                    MVSelectConfiguration.ActiveViewIndex = 1;
                    ChkShowInDisplayForm.Checked = (lookup.ShowInDisplayForm.HasValue? lookup.ShowInDisplayForm.Value : false);
                    return;
                }
                else
                {
                    webId = lookup.LookupWebId;
                    listId = new Guid(lookup.LookupList);
                    fieldInternalName = lookup.LookupField;

                    if (!lookup.ReverseLookupGuid.Equals(Guid.Empty))
                        reverseLookupId = lookup.ReverseLookupGuid.ToString();

                    DdlLookupFieldTargetList.Enabled = false;
                    DdlLookupFieldTargetWeb.Enabled = false;
                }
            }

            this.FillWebs(webId);
            this.FillList(listId);
            this.FillFields(fieldInternalName);
        }

        public void OnSaveChange(SPField field, bool isNewField)
        {
            AdvancedLookupField lookup = (field as AdvancedLookupField);

            if (!lookup.CountRelated)
            {
                //Read selected data from the form
                ListItem selected = DdlLookupFieldTargetWeb.Items[DdlLookupFieldTargetWeb.SelectedIndex];
                lookup.LookupWebId = new Guid(selected.Value);

                selected = DdlLookupFieldTargetList.Items[DdlLookupFieldTargetList.SelectedIndex];
                lookup.LookupList = selected.Value;

                selected = DdlLookupFieldTargetField.Items[DdlLookupFieldTargetField.SelectedIndex];
                lookup.LookupField = selected.Value;

                //TODO Additional Fields
                ////Browse additional fields
                //foreach (ListItem item in CblAdditionalFields.Items)
                //{
                //    if (item.Selected)
                //        lookup.SetAdditionalField(item.Value);
                //}

                //lookup.AllowMultipleValues = cbxAllowMultiValue.Checked;
                //lookup.UnlimitedLengthInDocumentLibrary = cbxUnlimitedLengthInDocLib.Checked;
            }
            else
                lookup.ShowInDisplayForm = ChkShowInDisplayForm.Checked;
        }


        #endregion
    }
}
